home *** CD-ROM | disk | FTP | other *** search
- ;EXECPRT.ASM 12/09/88
- ;COPYRIGHT 1988 BY DANIEL WOLF PH.D.
- ;EXEC I/O EXAMPLE FOR PRINTER OUTPUT
- ;USES DEVICE-BASED I/O WITH IOBLOCK AND REPLY MSGPORT
-
- SIZE.STDIO EQU $30
- SIZE.MP EQU $22
- CMD_WRITE EQU $3
-
- LVO.ALLOCMEM EQU $FFFFFF3A
- LVO.ADDPORT EQU $FFFFFE9E
- LVO.FINDTASK EQU $FFFFFEDA
- LVO.FREEMEM EQU $FFFFFF2E
- LVO.GETMSG EQU $FFFFFE8C
- LVO.WAITPORT EQU $FFFFFE80
- LVO.DOIO EQU $FFFFFE38
- LVO.CHECKIO EQU $FFFFFE2C
- LVO.ABORTIO EQU $FFFFFE20
- LVO.SENDIO EQU $FFFFFE32
- LVO.WAITIO EQU $FFFFFE26
- LVO.OPENDEVICE EQU $FFFFFE44
- LVO.FREESIGNAL EQU $FFFFFEB0
- LVO.CLOSEDEVICE EQU $FFFFFE3E
- LVO.ALLOCSIGNAL EQU $FFFFFEB6
-
- IO.COMMAND EQU $1C
- IO.DEVICE EQU $14
- IO.DATA EQU $28
- IO.LENGTH EQU $24
- LIST.HEAD EQU $0
- LIST.TAIL EQU $4
- MEMF_PUBLIC EQU $0
- MEMF_CLEAR EQU $10000
- MP.MSGLIST EQU $14
- MP.SIGTASK EQU $10
- MP.SIGBIT EQU $F
- MP.FLAGS EQU $E
- MSG.REPLYPORT EQU $E
- NODE.PRED EQU $4
- NODE.NAME EQU $A
- NODE.TYPE EQU $8
- NODE.PRI EQU $9
- NT_MSGPORT EQU $4
- NT_MESSAGE EQU $5
- PA_SIGNAL EQU $0
-
- MAIN
- BSR OPENPRINTER ;SET UP REPLY MSGPORT, SIGBIT, IOBLOCK THEN OPEN IT
- TST.L D0 ;IF PRINTER OPENING FAILED THEN
- BNE ERROR ; BRANCH OUT OF HERE
-
- MOVE.L IOREQ,A1 ;ELSE SET UP POINTERS TO IOBLOCK AND ASCII TEXT
- LEA IOTEXT,A0
- BSR PRINTERWRITE ;CALL PRINTER OUTPUT ROUTINE
-
- ; MOVE.L #18000,D0 ;A VERY DUMB DELAY LOOP TO WASTE SOME TIME
- ;LOOP ;IF YOU CHANGE PRINTERWRITE TO USE SENDIO.
- ; MOVE.L A0,-(SP) ;DOIO DOESN'T NEED THIS BECAUSE IT WAITS TIL I/O DONE.
- ; MOVE.L (SP)+,A0 ;WITHOUT THIS DELAY, ABORTIO (IN CLOSEPRINTER)
- ; DBRA D0,LOOP ;HAPPENS IMMEDIATELY - TOO FAST FOR SENDIO TO FINISH
-
- BSR CLOSEPRINTER ;FREE ALL RESOURCES ASSOCIATED WITH PRINTER DEVICE
-
- MOVEQ #0,D0
- ERROR ;AND WAVE GOODBYE
- RTS
-
- ;**************** APPROPRIATE EXEC AND I/O MACROS
-
- NEWLIST MACRO ;An
- MOVE.L \1,(\1) ;MOVE An TO (An)
- MOVE.L \1,LIST.HEAD(\1) ;SHUFFLE HEAD AND TAIL POINTERS
- ADD.L #LIST.TAIL,LIST.HEAD(\1)
- CLR.L LIST.TAIL(\1)
- MOVE.L \1,LIST.TAIL+NODE.PRED(\1) ;SO THIS PORT IS FIRST IN LIST
- ENDM
-
- OPENDEVICE MACRO ;*NAME,UNIT,*IOREQUEST,FLAGS
- LEA \1,A0 ;PUT NAME POINTER INTO A0
- MOVE.L #\2,D0 ;PUT UNIT NUMBER INTO D0
- MOVE.L \3,A1 ;PUT IOREQ POINTER INTO A1
- MOVE.L #\4,D1 ;PUT IOREQ FLAGS INTO D1
- SYSCALL OPENDEVICE ;NOW MAKE THE CALL
- ENDM
-
- CLOSEDEVICE MACRO ;*IOREQUEST ;SET UP TO CLOSE A DEVICE
- MOVE.L \1,A1 ;PUT IOREQ POINTER INTO A1
- SYSCALL CLOSEDEVICE ;NOW MAKE THE CALL
- ENDM
-
- ;*************** AND A FEW SIMPLE PROGRAMMING MACROS
-
- SYSCALL MACRO ;CALL A EXEC LIBRARY ROUTINE
- MOVE.L 4,A6
- JSR LVO.\1(A6)
- ENDM
-
- CALL MACRO ;CALL A KERNEL ROUTINE
- JSR LVO.\1(A6)
- ENDM
-
- PUSH MACRO ;PUSH A REGISTER ONTO STACK
- MOVEM.L \1,-(SP)
- ENDM
-
- PULL MACRO ;PULL A REGISTER FROM STACK
- MOVEM.L (SP)+,\1
- ENDM
-
- PUBLICMEM MACRO ;SIZE ;ALLOCATE SOME PUBLIC MEMORY
- MOVE.L #MEMF_PUBLIC!MEMF_CLEAR,D1
- MOVE.L \1,D0
- SYSCALL ALLOCMEM
- ENDM
-
- ;*************** GENERAL PURPOSE CREATE AND DELETE MSGPORT ROUTINES
-
- MAKEAPORT ;ENTER W/ PTR TO NAME IN A0, PRIORITY IN D0
- PUSH D0/A0 ;STASH THE REGS
- MOVE #-1,D0 ;DON'T CARE WHICH SIGBIT ALLOCATED FOR PORT
- SYSCALL ALLOCSIGNAL ;GET A SIGBIT
- MOVE.B D0,D7 ;STASH SIGBIT IN D7
- CMPI.B #-1,D0 ;IF ERROR -
- BEQ ERR_PORT ; BRANCH OUT FROM HERE
- PUBLICMEM #SIZE.MP ;ELSE ALLOCATE MEM FOR A MESSAGE PORT
- TST.L D0 ;IF ERROR -
- BEQ.S ERR_PORT ; BRANCH OUT FROM HERE
- MOVE.L D0,A4 ;ELSE PUT POINTER TO ALLOCATED MEM IN A4
- MOVEQ #0,D0
- MOVE.L D0,A1 ;FOR THIS TASK -
- CALL FINDTASK ;FIND THE TASK CONTROL BLOCK
- MOVE.L D0,MP.SIGTASK(A4) ;TELL PORT WHERE THE TCB IS
- PULL D0/A0 ;RESTORE THE REGS
- MOVE.L A0,NODE.NAME(A4) ;TELL LISTNODE OF PORT ITS NAME
- MOVE.B D0,NODE.PRI(A4) ;TELL LISTNODE OF PORT ITS PRIORITY
- MOVE.B #NT_MSGPORT,NODE.TYPE(A4) ;TELL LISTNODE OF PORT ITS TYPE
- MOVE.B #PA_SIGNAL,MP.FLAGS(A4) ;TELL PORT ITS FLAGS
- MOVE.B D7,MP.SIGBIT(A4) ;TELL PORT WHICH SIGBIT WAS ASSIGNED TO IT
- CMPA.L #0,A0 ;IF NO NAME
- BEQ.S PRIVATEPORT ; THEN ITS A PRIVATE PORT
- PUBLICPORT ;ELSE IT HAS A NAME AND ITS PUBLIC
- MOVE.L A4,A1 ;PUT PTR TO MEM OF PORT INTO A1
- CALL ADDPORT ;AND ADD THIS PORT TO EXISTING ONES
- BRA NOPORTERR ;AND FINISH UP
- PRIVATEPORT
- LEA MP.MSGLIST(A4),A0 ;SET UP PORT AS FIRST IN LIST
- NEWLIST A0 ;SEE MACRO ABOVE
- NOPORTERR
- MOVE.L A4,D0 ;PUT ADDRESS OF MSGPORT IN D0
- RTS
- ERR_PORT ;IF ERROR, SET D0 = 0
- MOVEQ #0,D0
- RTS
-
- KILLAPORT ;ENTER W/ POINTER TO MSGPORT IN A0
- PUSH A0 ;STASH THE POINTER ON THE STACK
- MOVEQ #0,D0
- MOVE.B MP.SIGBIT(A0),D0 ;AND FREE UP THE SIGNAL BIT
- CALL FREESIGNAL ;PREVIOUSLY ALLOCATED FOR THIS PORT
- PULL A1 ;AND THE PORT'S MEMORY
- MOVE.L #SIZE.MP,D0
- SYSCALL FREEMEM
- RTS
-
- ;**************** PRINTER DEVICE SUPPORT CODE
-
- OPENPRINTER
- MOVEQ #0,D0 ;SET NAME AND PRIORITY OF MSGPORT = 0
- MOVE.L D0,A0
- BSR MAKEAPORT ;AND CREATE REPLY MSGPORT FOR PRINTER I/O BLOCK
- TST.L D0
- BEQ ERR_OPENPRT
- MOVE.L D0,PMPORT ;ELSE THIS IS ADDR OF PRINTER MSGPORT
- BSR CREATEPRTIO ;USE MSGPORT TO HELP SET UP AN IOBLOCK
- TST.L D0 ;IF IOBLOCK BAD THEN
- BEQ ERR_OPENPRT ; BRANCH OUT FROM HERE
- MOVE.L PRTBUF,IO.DATA(A0) ;ELSE ATTACH BUFFER TO IOBLOCK
- MOVE.L #-1,IO.LENGTH(A0) ;AND SET ARBITRARY LENGTH I/O
- OPENPRT
- OPENDEVICE DEVNAME,0,IOREQ,0 ;NOW ATTACH PRINTER DEVICE TO IOBLOCK
- TST.L D0 ;IF NO PROBLEM THEN
- BEQ.S END_OPENPRT ; BRANCH TO END WITH D0 = 0
- ERR_OPENPRT
- MOVE.L #1,D0 ;ELSE FAIL WITH D0 = 1
- END_OPENPRT
- RTS
-
- CREATEPRTIO
- PUBLICMEM #SIZE.STDIO ;GET SOME MEM FOR AN IOBLOCK
- TST.L D0 ;IF UNSUCCESSFUL THEN
- BEQ ERR_PRTIO ; BRANCH OUT FROM HERE W/ D0 = 0
- MOVE.L D0,IOREQ ;ELSE D0 = PTR TO IOBLOCK
- MOVE.L D0,A0
- MOVE.B #NT_MESSAGE,NODE.TYPE(A0) ;SET ITS LISTNODE TYPE = 'MESSAGE'
- MOVE.B #0,NODE.PRI(A0) ;SET ITS LISTNODE PRIORITY = 0
- MOVE.L PMPORT,MSG.REPLYPORT(A0) ;SET ITS REPLYPORT = MSGPORT
- ERR_PRTIO
- RTS ;EXIT W/ D0 = ADDR OF IOBLOCK (0 IF ERROR)
-
- CLOSEPRINTER
- MOVE.L IOREQ,A1 ;GET ADDRESS OF IOBLOCK
- CALL CHECKIO ;SEE IF I/O DONE
- TST.L D0 ;IF DONE THEN
- BNE CLOSEPRT ; BRANCH OUT OF HERE
- MOVE.L IOREQ,A1 ;ELSE GET ADDRESS OF IOBLOCK
- CALL ABORTIO ;AND FORCE I/O TO END
- MOVE.L PMPORT,A0 ;NOW WAIT FOR A MESSAGE AT THE REPLY PORT
- CALL WAITPORT
- MOVE.L PMPORT,A0
- CALL GETMSG ;GET MESSAGE FROM PORT SAYING I/O ABORTED
- CLOSEPRT
- CLOSEDEVICE IOREQ ;NOW CLOSE DEVICE ATTACHED TO THE IOBLOCK
- MOVE.L PMPORT,A0
- BSR KILLAPORT ;AND FREE MSGPORT'S SIG BIT AND MEMORY
- MOVE.L IOREQ,A1 ;AND THE IOBLOCK'S MEMORY, TOO!
- MOVE.L #SIZE.STDIO,D0
- SYSCALL FREEMEM
- RTS
-
- PRINTERWRITE ;ENTER W/ PTR TO IOBLOCK IN A1
- ; W/ PTR TO NULL-TERMINATED ASCII IN A0
-
- MOVE #CMD_WRITE,IO.COMMAND(A1) ;PUT 'WRITE' INTO IOBLOCK COMMAND FIELD
- MOVE.L A0,IO.DATA(A1) ;PTR TO NULL-TERMINATED DATA
- MOVE.L #-1,IO.LENGTH(A1) ;#BYTES TO WRITE (-1 MEANS UNTIL A NULL)
- CALL DOIO ;AND CALL THE I/O ROUTINE (TRY SENDIO HERE)
- RTS
-
- DATA
-
- PMPORT DC.L 0 ;PTR TO IOBLOCK REPLY MSGPORT
- IOREQ DC.L 0 ;PTR TO PRINTER IOBLOCK
- PRTBUF DS.B 16 ;ABSOLUTELY NECESSARY LITTLE BUFFER
-
- DEVNAME
- DC.B 'printer.device',0 ;NAME OF PRINTER DEVICE
- EVEN
- IOTEXT
- DC.B 10,'Hello from the heart of Amiga Exec',13,10,0
- EVEN
- END
-
-